/*
 *  Copyright (C) 1993  Robert Davis
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of Version 2, or any later version, of 
 *  the GNU General Public License as published by the Free Software 
 *  Foundation.
 */

static char RCSId[]="$Id: CellScrollView.m,v 1.9 1993/05/18 03:54:44 davis Exp $";


/*
 *  Based heavily on the NeXTSTEP MiniExample CellScrollView
 *  by R. Dunbar Poor and Mai Nguyen.
 */

#import <appkit/Cell.h>
#import <appkit/nextstd.h>

#import "CellScrollView.h"
#import "EditMatrix.h"
#import "SubObjectCategory.h"

@implementation CellScrollView

- initFrame:(const NXRect *)frameRect
{
    [super initFrame:frameRect];
    return self;
}


- initMatrixCellClass:classId cols:(int)anInt
{
    Cell	*cell;
    NXSize	interCellSpacing = {0.0, 0.0};

    /* 
     *  This method should only be called once.  Check to see if 
     *  cellMatrix already exists.
     */
    if (cellMatrix || !classId)
	return nil;

    cell = [[classId alloc] init];
    isSubType = [cell respondsTo:@selector(setSubObject:)];
    [cell free];

    numCols = anInt;

    cellMatrix = [[EditMatrix alloc] initFrame: &frame
					  mode: NX_LISTMODE
				     cellClass: (cellClass = classId)
				       numRows: 0
				       numCols: numCols];

    [cellMatrix setIntercell:&interCellSpacing];
    [cellMatrix sizeToCells];		/* Resize matrix to contain cells    */
    [cellMatrix setAutosizeCells:YES];

    [cellMatrix setAutoscroll:YES];	/* Auto-scroll on drag if necessary  */
    [cellMatrix setAutosizing:NX_WIDTHSIZABLE];

    [[self setDocView:cellMatrix] free];

    [self setVertScrollerRequired:YES];
    [self setBorderType:NX_BEZEL];
    [self setAutoresizeSubviews:YES];
    /* This is the only way to get the clipview to resize too */
    [[cellMatrix superview] setAutoresizeSubviews:YES];

    if (cellSizePrototype) {
	NXRect	protoFrame;
	NXSize	docSize;

	[cellSizePrototype getFrame:&protoFrame];
	[self getContentSize:&docSize];

	if ((NX_WIDTH(&protoFrame) * numCols) > docSize.width)
	    [self setHorizScrollerRequired:YES];

	[cellMatrix sizeTo:(NX_WIDTH(&protoFrame) * numCols) :docSize.height];
	[cellSizePrototype free];
	cellSizePrototype = nil;
    } else {
	NXSize	docSize;
	/* Resize the matrix to fill the inside of the scrollview */

	[self getContentSize:&docSize];
	[cellMatrix sizeTo:docSize.width :docSize.height];
    }

    return self;
}


- free
{
    [cellMatrix free];
    return [super free];
}


- awakeFromNib
{
    return self;
}


- cellMatrix
{
  return cellMatrix;
}


- loadCol:(int)col from:(List *)cellObjects
/*
 *  Fill column col of the matrix with Cells, associate each Cell with 
 *  a cellObject.
 *
 *  Since we recycle the cells (via renewRows:cols:), we also set the 
 *  state of each cell to 0 and unhighlight it.  If we don't do that, 
 *  the recycled cells will display their previous state.
 */
{
    int i, cellCount;

    if (!isSubType)
	return nil;

    cellCount = [cellObjects count];

    if (col > numCols)
	numCols = col + 1;

    /* tell the matrix there are 0 cells in it (but don't deallocate them) */
    [cellMatrix renewRows:0 cols:numCols];
    [cellMatrix lockFocus];               /* for highlightCellAt::lit: */
    for (i=0; i < cellCount; i++) {
	id cell;
	/*
	 *  Add a row to the matrix.  (This doesn't necessarily 
	 *  allocate a new cell, thanks to renewRows:cols:).
	 */
	[cellMatrix addRow];
	cell = [cellMatrix cellAt:i:col];
	/* install the cellObject in that cell */
	[cell setSubObject:[cellObjects objectAt:i]];
	/* make sure the cell is neither selected nor highlighted */
	[cellMatrix highlightCellAt:i:0 lit:NO];
	[cell setState:0];
    }
    [cellMatrix unlockFocus];
    [cellMatrix sizeToCells];
    [cellMatrix display];
  
    return self;
}



// Shuts up the compiler about unused RCSId
- (const char *) rcsid
{
    return RCSId;
}


@end
